﻿using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;

namespace project_phoenix
{
    public class Animation
    {
        // name of this animation
        private string name;

        // This is the index offset for which way we are currently facing
        private int m_nFacingIndex;

        private Rectangle m_sourceRect;
        private Rectangle m_destRect;

        private int m_nNumFrames;
        private int m_nCurrentFrame;

        private int m_nSpriteWidth;
        private int m_nSpriteHeight;

        float timer;
        float interval;

        bool isLoop = true;
        bool isDone = false;

        public enum animType { Idle, Walking, Jumping, Blocking, Attacking, Hit, Dying, Dead }

        animType animationType;
        // Spritesheet layout::

        // idle (left, right)
        // walks (left, right)
        // jump (left, right)
        // block (left, right)
        // attack (left, right)
        // hit (left, right)
        // dying (left, right)
        // dead (left, right)
        public Animation(int fps, int sprite_width, int sprite_height, int numFrames, animType type, bool loops)
        {
            timer = 0.0f;
            interval = 1000.0f / fps;
            m_nSpriteHeight = sprite_height;
            m_nSpriteWidth = sprite_width;
            m_nNumFrames = numFrames;
            m_nFacingIndex = 0;
            animationType = type;
            isLoop = loops;
            isDone = false;
            name = type.ToString(); // save the name of the anim

        }

        // helper function to convert whatever type of anim this is to a height value
        private int ConvertTypeToHeight(animType type)
        {
            // Ugly switch for now - I could store this but its extra space for each animation
            switch (animationType)
            {
                case animType.Idle:
                    return 0;
                case animType.Walking:
                    return 1;
                case animType.Jumping:
                    return 2;
                case animType.Blocking:
                    return 3;
                case animType.Attacking:
                    return 4;
                case animType.Hit:
                    return 5;
                case animType.Dying:
                    return 6;
                case animType.Dead:
                    return 7;
                default:
                    return 0;
            }
        }

        public void Update(GameTime gameTime, Vector2 dir)
        {
            if (isDone == true)
                return;

            // Animation order = Right, Down, Left, Up
            if (dir.X < 0)
                m_nFacingIndex = 0;
            else
                m_nFacingIndex = m_nNumFrames;
 

            // update our time
            float deltaTime = (float)gameTime.ElapsedGameTime.TotalMilliseconds;
            timer += deltaTime;

            if (timer > interval)
            {
                // we dont want to go beyond the end since we might not be looping
                if(m_nCurrentFrame < m_nNumFrames)
                    m_nCurrentFrame++;

                // Check to see if we are looping or the animation is done
                if (m_nCurrentFrame > m_nNumFrames - 1 && isLoop == true)
                {
                    m_nCurrentFrame = 0;
                }
                // If we dont loop, dont show the animation
                else if (m_nCurrentFrame > m_nNumFrames - 1 && isLoop == false)
                {
                    m_nCurrentFrame = m_nNumFrames;
                    isDone = true;
                }
                
                timer = 0.0f;

            }
            // get our Y coordinate based on what type of animation this is
            int yCoord = m_nSpriteHeight * ConvertTypeToHeight(animationType);

            m_sourceRect = new Rectangle((m_nCurrentFrame + m_nFacingIndex) * m_nSpriteWidth, yCoord, m_nSpriteWidth, m_nSpriteHeight);
        }

        #region Properties

        public bool IsDone
        {
            get { return isDone; }
            set { isDone = value; }
        }
        
        public string Name
        {
            get { return name; }
            set { name = value; }
        }

        public int SpriteWidth
        {
            get { return m_nSpriteWidth; }
            set { m_nSpriteWidth = value; }
        }

        public int SpriteHeight
        {
            get { return m_nSpriteHeight; }
            set { m_nSpriteHeight = value; }
        }

        public Rectangle SourceRectangle
        {
            get { return m_sourceRect; }
            set { m_sourceRect = value; }
        }

        public Rectangle DestinationRectangle
        {
            get { return m_destRect; }
            set { m_destRect = value; }
        }

        public int CurrentFrame
        {
            get { return m_nCurrentFrame; }
            set { m_nCurrentFrame = 0; }
        }

        public bool IsLooping
        {
            get { return isLoop; }
            set { isLoop = value; }
        }
        #endregion

    }
}

